fix(sdk): apply v0.10.6 Android SDK doc QA fixes (DOC-27, DOC-37..DOC-60)#97
fix(sdk): apply v0.10.6 Android SDK doc QA fixes (DOC-27, DOC-37..DOC-60)#97iamstuffed wants to merge 29 commits into
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
There was a problem hiding this comment.
Pull request overview
This PR applies a comprehensive doc-QA pass across the Android (and cross-platform Kotlin) sections of the on-device SDK documentation against the v0.10.6 SDK release. It updates outdated import paths, replaces removed/renamed APIs in example snippets, corrects the Swift exportToJSON() return type, and removes a legacy leap/edge-sdk/overview.mdx stub that was blocking a redirect. Examples under examples/android/ are updated to match the same v0.10.6 API surface.
Changes:
- Update Kotlin imports (
model_downloader→downloader, top-level helpers →manifestpackage,MessageResponsefromai.liquid.leap→ai.liquid.leap.message) and replace removedChatMessage.user(...)factory with the primaryChatMessage(role, ...)constructor across docs and examples. - Replace removed/renamed Kotlin APIs:
setResponseFormatType(KClass)→ reifiedsetResponseFormatType<T>();LeapModelDownloaderconstructor signature (dropextraHTTPRequestHeaders, adddownloaderConfig/ioDispatcher, make request methodssuspend, deprecaterequestStopService);ChatMessageContentshape (Image(ImageUrl),Audio(InputAudio), removedtoJSONObject/fromJSONObjectin favor ofkotlinx.serialization);LeapFunctionParameterTypenested-class names nowLeap-prefixed;getPromptTokensSizeelevated toModelRunner; SwiftConversation.exportToJSON()returnsString(non-throwing). - Update voice-assistant snippet to send
AudioPcmF32directly instead of WAV re-encoding, and delete the legacyleap/edge-sdk/overview.mdxstub.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| leap/edge-sdk/overview.mdx | Removes legacy stub so the /leap/edge-sdk/overview redirect can take effect. |
| examples/android/web-content-summarizer.mdx | Update downloader import and ChatMessage construction. |
| examples/android/vision-language-model-example.mdx | Update downloader import. |
| examples/android/slogan-generator.mdx | Update downloader import and ChatMessage construction. |
| examples/android/recipe-generator-constrained-output.mdx | Update downloader import, reified setResponseFormatType, primary ChatMessage ctor. |
| examples/android/leap-koog-agent.mdx | Update downloader import. |
| deployment/on-device/sdk/voice-assistant.mdx | Update downloader import, reorder/correct imports, send raw float32 PCM instead of WAV. |
| deployment/on-device/sdk/utilities.mdx | Swift exportToJSON() now returns String; updated Kotlin LeapModelDownloader reference signature, nested ModelDownloadStatus, suspend/deprecation notes; reified setResponseFormatType and primary ChatMessage ctor. |
| deployment/on-device/sdk/quick-start.mdx | Downloader package rename, notification field rename, manifest-package imports, primary ChatMessage ctor. |
| deployment/on-device/sdk/openai-client.mdx | Correct MessageResponse import path. |
| deployment/on-device/sdk/model-loading.mdx | Updated LeapModelDownloader reference signature; removed obsolete ModelLoadingOptions.build. |
| deployment/on-device/sdk/messages-content.mdx | New ChatMessage secondary ctor, switch from JSONObject helpers to kotlinx.serialization, new ChatMessageContent (ImageUrl/InputAudio) shape, ImageUtils.fromBitmap suspend helper. |
| deployment/on-device/sdk/desktop-platforms.mdx | Imports moved to ai.liquid.leap.manifest; primary ChatMessage ctor. |
| deployment/on-device/sdk/conversation-generation.mdx | Swift exportToJSON() returns String; remove Kotlin exportToJSONArray / non-reified setResponseFormatType; document kotlinx.serialization round-trip. |
| deployment/on-device/sdk/constrained-generation.mdx | Reified setResponseFormatType/getJSONSchema; switch JSON parsing to kotlinx.serialization; rename createFromJSONObject → createFromJsonObject. |
| deployment/on-device/sdk/ai-agent-usage-guide.mdx | Correct MessageResponse and LeapModelDownloader import paths. |
| deployment/on-device/sdk/advanced-features.mdx | Reified setResponseFormatType; renamed LeapFunctionParameterType nested classes (LeapStr, LeapNum, etc.); getPromptTokensSize now on ModelRunner and is suspend. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…ction
- `ai.liquid.leap.model_downloader.*` → `ai.liquid.leap.downloader.*` for `LeapModelDownloader` and `LeapModelDownloaderNotificationConfig` (DOC-27).
- `notificationContentDownloading` → `notificationContentDownloadingTemplate` to match the real `LeapModelDownloaderNotificationConfig` field (DOC-37).
- JVM section: `ai.liquid.leap.LeapDownloader{,Config}` → `ai.liquid.leap.manifest.LeapDownloader{,Config}` (DOC-38).
- Replace 4× `ChatMessage.user(...)` (no such companion factory) with the real primary/secondary constructors (DOC-39).
Verified against leap-android-sdk v0.10.6 (commit cac3d06):
leap-sdk-model-downloader/src/androidMain/.../LeapModelDownloader.kt,
LeapModelDownloaderNotificationConfig.kt,
leap-sdk/src/commonMain/.../message/ChatMessage.kt,
leap-sdk/src/commonMain/.../manifest/LeapDownloader.kt.
Refs DOC-27, DOC-37, DOC-38, DOC-39.
…elLoadingOptions.build
- Rewrite the Kotlin (Android) `LeapModelDownloader` class block to the real 5-parameter primary constructor: `(Context, File?, LeapModelDownloaderNotificationConfig, LeapDownloaderConfig, CoroutineDispatcher)`. The doc previously listed a 4-parameter signature with a nonexistent `extraHTTPRequestHeaders` field (DOC-40).
- Drop the nonexistent `ModelLoadingOptions.Companion.build { ... }` factory from the Kotlin block and the example; switch the example to the direct primary-constructor form `ModelLoadingOptions(cpuThreads = 6, contextSize = 4096)`. `GenerationOptions.build {}` still exists and is unaffected; only `ModelLoadingOptions.build` was bogus (DOC-41).
Verified against leap-android-sdk v0.10.6 (commit cac3d06):
leap-sdk-model-downloader/src/androidMain/.../LeapModelDownloader.kt:56,
leap-sdk/src/commonMain/.../ModelLoadingOptions.kt:6.
Refs DOC-40, DOC-41.
… imports - `import ai.liquid.leap.MessageResponse` → `import ai.liquid.leap.message.MessageResponse` (DOC-43). - `import ai.liquid.leap.model_downloader.LeapModelDownloader` → `import ai.liquid.leap.downloader.LeapModelDownloader` (DOC-42). Verified against leap-android-sdk v0.10.6 (commit cac3d06): leap-sdk/src/commonMain/.../message/MessageResponse.kt, leap-sdk-model-downloader/src/androidMain/.../downloader/LeapModelDownloader.kt. Refs DOC-42, DOC-43.
…e-format API + Swift export return type - Drop the nonexistent `fun exportToJSONArray(): JSONArray` from the Kotlin `Conversation` interface block; switch the Kotlin "Export chat history" example to `kotlinx.serialization.encodeToString(conversation.history)` per the existing Utilities → Serialization pattern (DOC-44). - Drop the nonexistent `fun setResponseFormatType(kClass: KClass<*>)` overload from the documented `GenerationOptions` companion; switch the example to the real `inline fun <reified T> setResponseFormatType()` (DOC-60). Also fix a related bug not flagged by QA: Swift `Conversation.exportToJSON()` returns `String` (per `leap-sdk/src/appleMain/.../compat/ConversationExtensions.kt:45`), not `throws -> [[String: Any]]`. Updated the Swift interface block and Swift snippet accordingly. Verified against leap-android-sdk v0.10.6 (commit cac3d06): leap-sdk/src/commonMain/.../Conversation.kt, leap-sdk/src/commonMain/.../GenerationOptions.kt:126, leap-sdk/src/appleMain/.../compat/ConversationExtensions.kt:45. Refs DOC-44, DOC-60.
… reference - Drop the nonexistent `ChatMessage.toJSONObject()` / `ChatMessage.Companion.fromJSONObject(obj)` from the Kotlin data-class block; point the Kotlin Serialization tab at `kotlinx.serialization.Json.encodeToString` / `decodeFromString` (DOC-45). - Rewrite the Kotlin `ChatMessageContent` reference block: it is a `sealed class`, not `sealed interface`; drop the nonexistent `fun clone()` / `fun toJSONObject()` members and the nonexistent top-level `ChatMessageContent.fromJSONObject(obj)` extension (DOC-46). - Replace the documented `Image(jpegByteArray: ByteArray)` / `Audio(wavByteArray: ByteArray)` primary constructors with the real `Image(imageUrl: ImageUrl)` / `Audio(inputAudio: InputAudio)` and call out the convenience secondary constructors plus the derived `jpegByteArray` / `data` properties (DOC-47). - Replace `ChatMessageContent.Image.fromBitmap(...)` (no such companion method) with the real Android-only `ai.liquid.leap.message.ImageUtils.fromBitmap(Bitmap, Int)` (note: `suspend`) (DOC-48). Verified against leap-android-sdk v0.10.6 (commit cac3d06): leap-sdk/src/commonMain/.../message/ChatMessage.kt:10, leap-sdk/src/commonMain/.../message/ChatMessageContent.kt:15, leap-sdk/src/androidMain/.../message/ImageUtils.kt. Refs DOC-45, DOC-46, DOC-47, DOC-48.
… APIs - `JSONSchemaGenerator.getJSONSchema(CityFact::class)` → `JSONSchemaGenerator.getJSONSchema<CityFact>()`. The real method has a reified-T form and a `KSerializer<T>` form — no `KClass` overload (DOC-49). - `GeneratableFactory.createFromJSONObject(JSONObject(jsonContent))` → `GeneratableFactory.createFromJsonObject<T>(kxObj)`. Two bugs in one line: method name uses camelCase `Json` (not `JSON`), and the argument is `kotlinx.serialization.json.JsonObject` (not `org.json.JSONObject`) (DOC-50). - `setResponseFormatType(CityFact::class)` → `setResponseFormatType<CityFact>()` (DOC-60). - Update the prose, "Apply the schema" example, the schema-injection helper, and the Best-Practices parser snippet to use the corrected APIs consistently. Verified against leap-android-sdk v0.10.6 (commit cac3d06): leap-sdk/src/commonMain/.../structuredoutput/JSONSchemaGenerator.kt, leap-sdk/src/commonMain/.../structuredoutput/GeneratableFactory.kt, leap-sdk/src/commonMain/.../GenerationOptions.kt:126. Refs DOC-49, DOC-50, DOC-60.
…Pcm16Wav helper - `import ai.liquid.leap.MessageResponse` → `import ai.liquid.leap.message.MessageResponse` (DOC-51). - `import ai.liquid.leap.model_downloader.LeapModelDownloader` → `import ai.liquid.leap.downloader.LeapModelDownloader` (DOC-52). - Drop the import and call of `ai.liquid.leap.message.encodePcm16Wav(...)` — no such top-level function exists in v0.10.6. Switch the Kotlin `LeapVoiceConversation.generateResponse` example to `ChatMessageContent.AudioPcmF32(audioSamples, sampleRate)`, which skips the WAV re-encode entirely (DOC-53). Verified against leap-android-sdk v0.10.6 (commit cac3d06): leap-sdk/src/commonMain/.../message/MessageResponse.kt, leap-sdk-model-downloader/src/androidMain/.../downloader/LeapModelDownloader.kt, leap-sdk/src/commonMain/.../message/ChatMessageContent.kt (AudioPcmF32 variant), no occurrence of encodePcm16Wav in leap-sdk/src. Refs DOC-51, DOC-52, DOC-53.
- `ai.liquid.leap.LeapDownloader` → `ai.liquid.leap.manifest.LeapDownloader` (DOC-54, issue 25).
- `ai.liquid.leap.LeapDownloaderConfig` → `ai.liquid.leap.manifest.LeapDownloaderConfig` (DOC-54, issue 26).
- `ai.liquid.leap.ModelSource` → `ai.liquid.leap.manifest.ModelSource` (DOC-54, issue 27).
- Replace `ChatMessage.user("What is the capital of France?")` (nonexistent companion factory — same as DOC-39) with `ChatMessage(ChatMessage.Role.USER, "What is the capital of France?")`.
Verified against leap-android-sdk v0.10.6 (commit cac3d06):
leap-sdk/src/commonMain/.../manifest/LeapDownloader.kt,
leap-sdk/src/commonMain/.../manifest/LeapDownloaderConfig.kt,
leap-sdk/src/commonMain/.../manifest/ModelSource.kt,
leap-sdk/src/commonMain/.../message/ChatMessage.kt.
Refs DOC-54, DOC-39.
…nloadStatus - Rewrite the Kotlin status-polling block to match the real v0.10.6 surface: * `LeapModelDownloader` primary constructor has 5 parameters: `(Context, File?, LeapModelDownloaderNotificationConfig, LeapDownloaderConfig, CoroutineDispatcher)`. The previous block listed a nonexistent `extraHTTPRequestHeaders` field (same as DOC-40). * `requestDownloadModel` is `suspend` (DOC-55, issue 28). * `requestStopDownload` is `suspend` (DOC-55, issue 29). * `requestStopService` is `@Deprecated` *and* `suspend` (DOC-55, issue 30). * `ModelDownloadStatus` is nested under `LeapModelDownloader` — there is no top-level `ai.liquid.leap.downloader.ModelDownloadStatus` (DOC-56). - Update the bullet list under the block to reflect the new modifiers and deprecation. - Putting-it-together example: replace `setResponseFormatType(TripRecommendation::class)` with `setResponseFormatType<TripRecommendation>()` (DOC-60) and replace `ChatMessage.user(...)` with the real constructor (DOC-39). - Fix a related Swift bug not flagged by QA: `Conversation.exportToJSON()` returns `String`, not `throws -> [[String: Any]]` (per leap-sdk/src/appleMain/.../ConversationExtensions.kt:45). Verified against leap-android-sdk v0.10.6 (commit cac3d06): leap-sdk-model-downloader/src/androidMain/.../downloader/LeapModelDownloader.kt (lines 56, 268, 349, 374, 450, 501). Refs DOC-55, DOC-56, DOC-39, DOC-60.
…nd drop bogus runner cast - Rewrite the Kotlin `LeapFunctionParameterType` nested classes to the real names with a `Leap` prefix — `LeapStr`, `LeapNum`, `LeapInt`, `LeapBool`, `LeapNull`, `LeapArr`, `LeapObj`. The prefix exists upstream specifically to avoid shadowing `kotlin.String`, `kotlin.Number`, etc., and the Function Calling guide on the adjacent page already uses these names (DOC-57, issues 32–38). - Remove the `runner as? LiquidInferenceEngineRunner` cast around `getPromptTokensSize`. `getPromptTokensSize(messages:, addBosToken:)` is declared directly on the cross-platform `ModelRunner` interface in v0.10.6, so no cast is needed. `LiquidInferenceEngineRunner` only exists as an Apple compat class at `ai.liquid.leap.compat.LiquidInferenceEngineRunner` — there is no `ai.liquid.leap.LiquidInferenceEngineRunner`, and on Kotlin Android the cast was always unresolved (DOC-58). - Drop the nonexistent `fun setResponseFormatType(kClass: KClass<*>)` overload from the documented Kotlin `GenerationOptions` companion; the only real method is `inline fun <reified T> setResponseFormatType()` (DOC-60). Verified against leap-android-sdk v0.10.6 (commit cac3d06): leap-sdk/src/commonMain/.../function/LeapFunctionParameterType.kt, leap-sdk/src/commonMain/.../ModelRunner.kt:39, leap-sdk/src/commonMain/.../GenerationOptions.kt:126, leap-sdk/src/appleMain/.../compat/LiquidInferenceEngineRunner.kt. Refs DOC-57, DOC-58.
- `import ai.liquid.leap.MessageResponse` → `import ai.liquid.leap.message.MessageResponse` in the hybrid on-device + cloud routing Kotlin (Android) snippet. Real package is `ai.liquid.leap.message`, same as DOC-43 and DOC-51 on other pages (DOC-59). Verified against leap-android-sdk v0.10.6 (commit cac3d06): leap-sdk/src/commonMain/.../message/MessageResponse.kt. Refs DOC-59.
…mple pages The example pages under examples/android/ had the same outdated patterns flagged by the QA pass on the SDK reference pages: - Wrong import package `ai.liquid.leap.model_downloader.LeapModelDownloader` → `ai.liquid.leap.downloader.LeapModelDownloader` across all 5 files (DOC-27 root cause). - `setResponseFormatType(Recipe::class)` → `setResponseFormatType<Recipe>()` plus the matching prose mention in recipe-generator-constrained-output.mdx (DOC-60 root cause). - `ChatMessage.user(prompt)` → `ChatMessage(ChatMessage.Role.USER, prompt)` across recipe-generator-constrained-output, slogan-generator, and web-content-summarizer (DOC-39 root cause). Verified against leap-android-sdk v0.10.6 (commit cac3d06). Refs DOC-27, DOC-39, DOC-60.
…ct fires The file at leap/edge-sdk/overview.mdx was a leftover from the pre-unification "LEAP Edge SDK" page tree. docs.json already redirects `/leap/edge-sdk/overview` → `/deployment/on-device/sdk/quick-start`, but Mintlify prefers existing files over redirect rules, so the legacy page kept rendering with broken internal links (e.g. `./ios/ios-quick-start-guide`). Removing the file lets the redirect fire. Verified with `npx mintlify dev` after deletion: GET /leap/edge-sdk/overview → 307 /deployment/on-device/sdk/quick-start. All 27 previously-known-good legacy URLs (10 android/, 10 ios/, plus :slug* wildcards and the Edge SDK paths) now return 3xx redirects to the unified /deployment/on-device/sdk/* tree.
…leFactory reference signatures Audit follow-up. The reference signature blocks for `JSONSchemaGenerator` and `GeneratableFactory` in this page still showed the pre-v0.10.6 surface — a `KClass` overload for both, and `JSONObject` (the `org.json` type) on the factory. Real signatures (verified against `leap-sdk/src/commonMain/.../structuredoutput/JSONSchemaGenerator.kt` and `GeneratableFactory.kt`): - `JSONSchemaGenerator.getJSONSchema(serializer: KSerializer<T>, indentSpaces: Int? = null): String` plus the reified-T form. No `KClass` overload. - `GeneratableFactory.createFromJsonObject(jsonObject: kotlinx.serialization.json.JsonObject, serializer: KSerializer<T>): T` plus the reified-T form. Note camelCase `Json` in the method name and the `kotlinx.serialization.json.JsonObject` argument (not `org.json.JSONObject`). The working code snippets on this page and on `constrained-generation.mdx` already use the correct reified syntax — only the reference tables were stale. Same root cause as DOC-49 and DOC-50; tightening the reference signatures so they match the example usage. Refs DOC-49, DOC-50.
`ChatMessageContent.Image(jpegByteArray: ByteArray)` is a convenience secondary constructor that wraps the bytes in a `data:image/jpeg;base64,...` URL (see `leap-sdk/src/commonMain/.../message/ChatMessageContent.kt` — `JPEG_BASE64_DATA_URL_PREFIX` is hard-coded). Passing PNG bytes still compiles but produces a content-type mismatch on the wire that the model will reject or misinterpret. Switch the example to `ImageUtils.fromBitmap(bitmap, compressionQuality = 85)` — the canonical Android helper, which JPEG-encodes via `Bitmap.compress(JPEG, ...)` on `Dispatchers.Default` and returns a `ChatMessageContent.Image` ready to send. Drop the now-unused `ByteArrayOutputStream` import. Refs DOC-48.
…redoutput package @Generatable and @Guide are declared in ai.liquid.leap.structuredoutput (Annotations.kt) and are not re-exported from the top-level ai.liquid.leap package. Copy-pasting the original snippet failed with 'unresolved reference'. Refs DOC-49/50, DOC-60.
8b13e7f to
6650914
Compare
…ated Swift APIs
JSONSchemaGenerator throws LeapGeneratableSchematizationException("Type must be
@serializable to generate JSON Schema") when the type lacks @serializable
(leap-sdk/src/commonMain/.../JSONSchemaGenerator.kt:53-59), so the CityFact,
Recipe, and NutritionInfo snippets were runtime-broken. @Generatable requires a
description (no Kotlin default) and @Guide is @target(AnnotationTarget.PROPERTY)
only (Annotations.kt:14,21), so the recipe-generator example with
class-level @Guide and no @Generatable description was compile-broken.
Also corrects the Swift side: setResponseFormat(type:) does not exist (canonical
path is options.with(jsonSchema: T.jsonSchema()), or
GenerationOptionsCompat.setResponseFormat(jsonSchema:)),
JSONSchemaGenerator.getJSONSchema(for:) is non-throwing (no try), and
LeapSDKMacros must be imported alongside LeapModelDownloader. Replaces the
"computed via reflection" claim with the actual mechanism (kotlinx.serialization
descriptor) and drops the misleading 0.7 default-temperature reference per
project CLAUDE.md guidance.
…cated VLM API leap-koog-agent: Apps cannot read /tmp/ on Android — switch the ADB commands and modelPath to /data/local/tmp/liquid/ (matches recipe-generator and VLM example). Drop the inconsistent .bundle filename reference; the SDK ships GGUFs. vision-language-model-example: the page mixed LFM2-VL-1.6B and LFM2.5-VL-1.6B — unify on LFM2.5-VL-1.6B (matches the actual ModelSource(modelName: "LFM2.5-VL-1.6B") load call). Replace the askQuestionAboutImage snippet that called the nonexistent vlmModel.generateFromImage(image, prompt, maxTokens:) with the real ImageUtils.fromBitmap + Conversation.generateResponse pipeline. Rewrite the lifecycle section to call ModelRunner.unload() (suspend) with a re-entrance guard instead of the made-up releaseModel()/initializeModel() pair.
…Swift factory APIs quick-start: MessageResponse.ReasoningChunk has `reasoning`, not `text` (MessageResponse.kt:50). The previous Kotlin snippet would not compile. Also replace nonexistent Swift .image(jpegData) / .audio(wavData) positional factories with the real ChatMessageContent.fromJPEGData(_:) / .fromWAVData(_:) (ChatMessageContentExtensions.swift:14-58), pass reasoningContent: / functionCalls: explicitly (Kotlin defaults do not propagate through K/N), and steer the Swift GenerationOptions snippet to the canonical parameterless init + .with(...) builder chain. model-loading: DownloadedModelManifest.manifest is typed as Manifest, not ModelManifest (Manifest.kt:30). LiquidInferenceEngineOptions.bundlePath is declared `val`, so the Swift surface is `let`, not `var`. SamplingParameters includes a topK field that was missing from the snippet. Drop the misleading "evictUnusedModel is a no-op" reference — that method is private to the service process and not part of any public API.
…t and Content enum The Swift API is generated by Kotlin/Native + SKIE from the Kotlin types — there is no native Swift `struct ChatMessage`, no `enum ChatMessageContent`, no `ChatMessageRole: String` with raw values, and no `init(from: [String: Any])` on either type. Replace those fabrications with the real bridged-class surface where Kotlin parameter defaults do not propagate (init requires all four args) and the role enum is ChatMessage.Role (no String raw-value backing). Drop the nonexistent ChatMessageContent.fromUIImage(image, compressionQuality:) (JPEG quality is hardcoded to 0.85 in the iOS overlay) and the entirely fictitious fromNSImage helper. Replace .audio(wavData) positional factory calls with the real ChatMessageContent.fromWAVData(_:). Fix the Kotlin secondary constructor parameter name (textContent, not text) per ChatMessage.kt:74-77, and add the nested ImageUrl/InputAudio types + toWavBytes()/toAudio() helpers that were missing. Also corrects the prose: ChatMessageContent is a sealed class, not a sealed interface; LeapSerializationException, not LeapSerializationError.
… + SKIE export
Conversation is a Kotlin interface bridged to Swift as a protocol with `{ get }`
properties, not a Swift class with `let` / `private(set) var`. Swift parameter
labels match the Kotlin parameter names (`function:`, `functions:`,
`message:`) — there are no underscore-labeled `_ function:` / `_ message:`
overloads. Generation methods return `SkieSwiftFlow<MessageResponse>` (iterable
with `for try await`), not `AsyncThrowingStream<MessageResponse, Error>`.
Drop the "Swift only" qualifier on `functions` — the property is on the
Kotlin Conversation interface (Conversation.kt:25), available on every
platform. Change every MessageResponse sealed subtype to `data class`
(MessageResponse.kt:41-83) so equals/hashCode/copy semantics survive.
`GenerationStats.tokenPerSecond` is non-nullable Float; only the parent
`stats: GenerationStats?` is nullable. Replace the fabricated Swift
`setResponseFormat<T>(type:)` and `LeapFunctionCallParserProtocol` types
with the real canonical paths (builder `.with(jsonSchema:)` and the
LeapFunctionCallParser class — there is no Protocol suffix). Switch
GenerationOptions Swift examples from the partial kwarg init (which doesn't
exist because Kotlin defaults don't propagate) to the parameterless init +
`.with(...)` builder chain from ConvenienceExtensions.swift.
utilities: LeapError is a typealias for LeapException (Kotlin open class), not a Swift enum — replace fabricated cases (.modelLoadingFailure, .generationFailure, .promptExceedContextLengthFailure, .serializationFailure) with the real LeapException subclass names (LeapException.kt:21-38). Drop the nonexistent onErrorCallback reference and the fictitious ChatMessage(from: [String: Any]) initializer. Note that ModelDownloadStatus nesting differs by platform (Android: nested under LeapModelDownloader; Apple: top-level with a different payload — DownloadInProgress(progress: Double) vs the Android variant). Fix LeapDownloaderConfig.saveDir which takes a String, not a File (so cacheDir needs .absolutePath on Android). Replace the partial-args Swift GenerationOptions init + setResponseFormat(type:) with the builder + jsonSchema form. advanced-features: LeapFunctionCallParserProtocol does not exist — the type is the abstract Kotlin class LeapFunctionCallParser, bridged to Swift as a class with the same name. Remove the fabricated mutating setResponseFormat<T>(type:) — Swift schema setting goes through .with(jsonSchema: T.jsonSchema()) (or GenerationOptionsCompat). Steer the Swift GenerationOptions snippet to the parameterless init + chained .with(...) builders rather than a full-arg init that would require all 13 fields. Add the LeapSDKMacros import for JSONSchemaGenerator and drop the non-throwing-method `try`. Replace the parser-implementation prose with "subclass" since LeapFunctionCallParser is an abstract class on both platforms.
…e Swift labels LeapFunction and LeapFunctionParameter both carry @ObjCName annotations on their description parameters (LeapFunction.kt:19, LeapFunctionParameter at line 71), so the Swift initializer labels are functionDescription: and parameterDescription:, not description:. LeapFunctionParameter.optional has no Swift default — pass optional: false for required parameters (Kotlin defaults don't propagate through K/N + ObjC). The previously documented Swift API (.string(StringType()), .number(NumberType()), .array(ArrayType(...)), .null(NullType) plus their wrapper types) is entirely fabricated. The real Swift surface preserves the Kotlin nested-class names from LeapFunctionParameterType.kt:35-115: LeapFunctionParameterType.LeapStr(enumValues:description:), .LeapNum(enumValues:description:), .LeapInt(enumValues:description:), .LeapBool(description:), .LeapArr(itemType:description:), .LeapObj(properties:required:description:), .LeapNull() (no description). SKIE does NOT generate cleaner .string(...) / .number(...) aliases — the "Swift bindings expose the same primitives under cleaner names" claim was wrong. Rewrites every Swift snippet in the page to use the real class names plus ObjCName-renamed labels, and corrects the LeapFunctionCall.arguments type to [String: Any] (the ObjC bridge collapses Kotlin Any? to non-optional id).
…nce and pin ai-agent-usage-guide: Swift's stdlib has no asyncMap — rewrite the agent loop's tool-execution pass as a sequential `for await` accumulation. Fix the missing `workingConv.` prefix on the Kotlin modelRunner reference (Conversation.kt:16 declares `val modelRunner: ModelRunner` on the interface). Replace .image(jpegData) / .audio(wavData) positional factories with the real ChatMessageContent.fromJPEGData(_:) / .fromWAVData(_:). Add the missing reasoningContent: nil / functionCalls: nil args on every Swift ChatMessage call. Switch the Swift GenerationOptions call to the builder chain. Correct the Kotlin/Native version pin: only v0.10.0, v0.10.1, and v0.10.6 exist on the android-sdk repo (v0.10.2 and v0.10.3 were never tagged); fixes shipped via v0.10.4.x on the SPM repo and v0.10.6 on the android-sdk repo. Pin to 0.10.6 or newer. Annotate the audio.samples access with a note that it's a KotlinFloatArray (needs the floatArrayToNSData bridge before passing to a [Float]-typed renderer). voice-assistant: fraction in downloadProgress is Kotlin Double — cast to Float before passing to setModelProgress(fraction: Float, ...). Add the missing `import android.os.Bundle` to the Compose snippet. Rewrite the AppleVoiceConversation Swift adapter to actually conform to the protocol — the LeapUI VoiceConversation protocol method takes LeapUi.KotlinFloatArray / LeapUi.KotlinInt (the LeapUI and LeapSDK frameworks have separate Kotlin runtimes; cross-framework Kotlin types do not interconvert without an NSData bridge). Add the missing systemPrompt: nil in the Swift modelRunner.createConversation() call (no Swift default). Correct the Compose "transitively" claim — leap-ui depends on Compose with implementation scope, so the runtime artifacts are pulled in but the APIs are not re-exported.
…Swift API
openai-client: the leap-sdk-openai-client Kotlin module does NOT apply the
SKIE plugin (verified in leap-sdk-openai-client/build.gradle.kts:3-11 — only
leap-sdk, leap-sdk-model-downloader, and leap-ui do), so Flow<ChatCompletionEvent>
is not bridged to Swift AsyncSequence and onEnum(of:) is not generated for
ChatCompletionEvent. The "for try await event in client.streamChatCompletion(...)"
+ "switch onEnum(of: event)" Swift example would not compile. Rewrite the
Swift section with a Warning callout explaining the SKIE absence and a manual
Flow.collect(collector: FlowCollector { ... }) + `as?` downcast pattern.
Also corrects the streaming claim: streamChatCompletion(...) forces
request.copy(stream = true) on the outgoing payload (OpenAiClient.kt:49),
overriding whatever stream field the caller set — not a default. Drop the JVM
artifact claim entirely: leap-sdk-openai-client/build.gradle.kts declares no
jvm() target, and Maven Central confirms no leap-openai-client-jvm artifact
exists (https://repo1.maven.org/maven2/ai/liquid/leap/leap-openai-client-jvm/
returns 404). For JVM-only hosts, recommend a standard OpenAI Java/Kotlin SDK.
desktop-platforms: same JVM-artifact correction (drop the commented
`// implementation("ai.liquid.leap:leap-openai-client:0.10.6")` from the JVM
example). Correct the JDK row: leap-sdk's jvm() target inherits
kotlin.jvmToolchain(17) — JDK 11 only applies to the Android target. Correct
the broken-version block: v0.10.2 was never published (only v0.10.0, v0.10.1,
and v0.10.6 on the android-sdk repo); fixes shipped across v0.10.4.x on the
SPM repo and v0.10.6 on the android-sdk repo. Pin to v0.10.6 or newer.
Drop the false Mac Catalyst claim — the released LeapSDK.xcframework slices
are only ios-arm64, ios-arm64-simulator, and macos-arm64. Add a note that the
simulator slice is ARM64-only (no Intel-Mac simulator support). Fix the
mmap-default changelog anchor (#memory-mapped-model-loading-by-default).
cloud-ai-comparison: correct `MessageResponse.functionCalls` to
`MessageResponse.FunctionCalls` (the sealed-variant name, not a property).
Replace the fabricated `GenerationOptions.setResponseFormat(type:)` cell with
the real per-platform helpers (Swift options.with(jsonSchema: T.jsonSchema()),
Kotlin setResponseFormatType<T>()). Fix the streaming-response cell to name
the real Swift type (SkieSwiftFlow<MessageResponse>, iterable with
`for try await`) instead of AsyncThrowingStream. Switch the role-tagged
message example to ChatMessage(role:textContent:) to avoid the 4-arg
content-list form.
v0.10.7 closes the JVM gap on leap-openai-client — the module now publishes `jvm` (Ktor CIO) and `wasmJs` (Ktor Js) targets alongside the prior android / apple / linux / mingw slices (PR Liquid4All/leap-android-sdk#256). Bytecode across all -jvm artifacts is now uniformly Java 11 (was silently 17 / 21 through v0.10.6). iOS Swift surface unchanged from v0.10.6. Docs changes: - leap-sdk-changelog: add v0.10.7 entry, bump "Latest release" header. - openai-client: replace the K/N-only Gradle tab with a JVM tab plus a separate Kotlin/Native tab; drop the audit-era "no JVM target" warning but keep the SKIE-absence warning (SKIE is still not applied to the openai-client module in v0.10.7). - desktop-platforms: restore the leap-openai-client JVM dependency in the Gradle snippet; revert JDK row to JDK 11 (matches the v0.10.7 bytecode hardening); extend the K/N broken-version warning to cite v0.10.7 in the fix cascade. - voice-assistant: reword the Wasm-preview disclaimer from "v0.10.6 release notes" to "through v0.10.7" — Wasm is still preview-only. - Bump version pins (Gradle coords, SPM download URLs, version catalog values, nativelibs plugin version, Maven <version>, recipe-generator step) from 0.10.6 to 0.10.7. Preserved feature-introduction markers ("v0.10.6+", "since v0.10.6", etc.) — those still point at the version that introduced the feature.
Verified every doc claim against the actual published artifacts (Maven Central + GitHub Releases SPM zips + leap-android-sdk@98a7c46 source). Four real bugs surfaced and fixed: 1. **Stale SPM checksums.** Bulk-bumping the SPM download URLs from v0.10.6 to v0.10.7 in the prior commit didn't update the SHA-256 values next to them. SPM would reject all four .binaryTarget pins. Replaced with verified v0.10.7 SHA-256 (cross-checked against leap-sdk@v0.10.7:Package.swift and local shasum -a 256 of each downloaded XCFramework zip). 2. **Mac Catalyst claim removed from quick-start.** The doc has said "Mac Catalyst 17.0+ also supported" since the initial 9dadc96 docs landing (PR #94). The desktop-platforms audit caught the same falsehood there, but quick-start was missed until artifact verification — Package.swift declares only .iOS(.v17) and .macOS(.v15); every shipped XCFramework Info.plist lists exactly ios-arm64 / ios-arm64-simulator / macos-arm64 LibraryIdentifiers (no maccatalyst slice). Rewrote line to say ARM64-only explicitly and cite the slice inventory. 3. **Wrong Swift function-name case in openai-client.** Docs said `OpenAiClientKt.openAiClient(config:)`. The actual Swift name from K/N export is `OpenAiClientKt.OpenAiClient(config:)` (capital O — Kotlin's PascalCase top-level fun name is preserved). Verified against LeapOpenAIClient.framework/Headers/LeapOpenAIClient.h line 494: `OpenAiClientConfig:(...) swift_name("OpenAiClient(config:)")`. 4. **Nested-class Swift names in openai-client.** Without SKIE applied to the openai-client module, K/N flattens nested classes — they are NOT exposed as `ChatMessage.User` / `ChatCompletionEvent.Delta` in Swift, but as `ChatMessageUser` / `ChatCompletionEventDelta`. Verified against the framework header swift_name attributes at lines 285 (ChatMessageAssistant), 304 (ChatMessageSystem), 323 (ChatMessageUser), 157 (ChatCompletionEventDelta), 176 (ChatCompletionEventDone), 195 (ChatCompletionEventError). Updated both the basic-usage Swift example and the hybrid-routing ViewModel snippet. Added an inline note explaining the flattening so readers know to apply the same pattern to other Kotlin nested types if they extend the example. Verification footprint that produced these findings: - Maven Central probe: 27 artifacts at 0.10.7 (all 200, including new leap-openai-client-{jvm,wasm-js}) - 6 jars unpacked: bytecode major = 0x37 (Java 11) across leap-sdk-jvm, leap-openai-client-jvm, leap-ui-jvm, leap-sdk-android, leap-ui-android, leap-model-downloader-android - 4 XCFramework zips downloaded from github.com/Liquid4All/leap-sdk/releases/download/v0.10.7/: all 3 documented slices, no Catalyst, no Intel simulator - LeapModelDownloader.framework verified: @ObjCName(swiftName= "ModelDownloader"), dual-import #error guard, dynamic Mach-O, bundled inference-engine dylibs under Frameworks/, re-exports LeapSDK Kotlin types (4 swift_name hits for Conversation / ModelRunner / ChatMessage / GenerationOptions) - LeapOpenAIClient.framework verified: SKIE absent (no Modules/*.swiftmodule, no Headers/*-Swift.h, zero SkieSwiftFlow / onEnum hits; LeapSDK has those by contrast) - KMP source at 98a7c46 verified: ChatMessage primary ctor unchanged (4 fields), LeapFunctionParameterType subclasses unchanged (LeapStr/LeapNum/LeapInt/LeapBool/LeapArr/LeapObj/LeapNull), @ObjCName labels on LeapFunction line 19 / 71, root build.gradle.kts:128-152 centralizes JvmTarget.JVM_11 in subprojects {}, openai-client build still has no skie plugin - POM dependency check: leap-openai-client-jvm pulls ktor-client-cio-jvm (matches "CIO Ktor engine" claim), -android pulls ktor-client-okhttp-jvm (matches "OkHttp-engine Ktor client" claim), -wasm-js pulls ktor-client-js-wasm-js (matches "Ktor Js engine" claim) - Historical pin check: leap-openai-client-jvm and -wasm-js are 404 at every prior 0.10.x release (0.10.0 through 0.10.6) — "landed in v0.10.7" framing in the changelog is correct
…next release The current SKIE-absence warning told Swift readers what to do today (manual Flow.collect + as? downcast, flattened ChatMessageUser / ChatCompletionEventDelta type names) but didn't signal that this is transitional. Add a 'Coming in the next release' bullet under the warning callout in openai-client.mdx and a sentence in the v0.10.7 changelog entry naming the planned changes: - for try await over streamChatCompletion(...) - onEnum(of: event) exhaustive switching - Nested-class Swift names (ChatCompletionEvent.Delta) instead of the current flattened form (ChatCompletionEventDelta) - Swift convenience inits / builders for OpenAiClientConfig Frame it as 'pin to v0.10.7 if you need the current behavior frozen, otherwise expect the more ergonomic surface to land soon' so readers copy-pasting today's manual-collector code know it'll work but isn't the long-term shape.
Summary
Fixes every Android-SDK doc QA finding from Linear (DOC-27, DOC-37..DOC-60 — 25 tickets, 41 numbered findings) against the v0.10.6 SDK. Every snippet was verified against
leap-android-sdkat commitcac3d06(v0.10.6 publish snapshot). Examples underexamples/android/had the same outdated patterns and are fixed in the same PR.What changed (one commit per page for clean review)
fbb38dbsdk/quick-start.mdxb7dc763sdk/model-loading.mdxd8d825asdk/ai-agent-usage-guide.mdx3770f5csdk/conversation-generation.mdxexportToJSON()return type)7cb0e03sdk/messages-content.mdxd2cb11asdk/constrained-generation.mdx06800f0sdk/voice-assistant.mdx2a3456bsdk/desktop-platforms.mdx2af37d7sdk/utilities.mdx24fe022sdk/advanced-features.mdxbff0d0dsdk/openai-client.mdx972b174examples/android/*.mdxb71e453leap/edge-sdk/overview.mdx/leap/edge-sdk/overviewredirect)863fd87sdk/advanced-features.mdxaudit follow-upJSONSchemaGenerator/GeneratableFactoryreference signatures)63f2040examples/android/vision-language-model-example.mdxaudit follow-upImage(ByteArray)ctor hard-codesdata:image/jpeg;base64,…)455bf7e8b13e7fexamples/android/recipe-generator-constrained-output.mdxaudit follow-upGeneratable/Guidefromai.liquid.leap.structuredoutput, not the root package)Bonus (caught on critical review, not in the QA report)
Three discrepancies surfaced only after re-auditing against the v0.10.6 source — they were not in the original QA list:
Conversation.exportToJSON()returnsString, not[[String: Any]](perleap-sdk/src/appleMain/.../compat/ConversationExtensions.kt:45). Fixed in3770f5c/2af37d7.advanced-features.mdxdocumentedJSONSchemaGenerator.getJSONSchema(klass: KClass<T>)/GeneratableFactory.createFromJSONObject(jsonObject: org.json.JSONObject)— neither overload exists. Real signatures useKSerializer<T>+ reified, andkotlinx.serialization.json.JsonObject. Fixed in863fd87.vision-language-model-example.mdxencoded the bitmap as PNG before passing toChatMessageContent.Image(ByteArray). The convenience secondary ctor hard-codes adata:image/jpeg;base64,…URL prefix, so PNG bytes shipped with a wrong content-type label. Now usesImageUtils.fromBitmap(...)which JPEG-encodes viaBitmap.compress(JPEG, ...). Fixed in63f2040.Note
sdk/function-calling.mdxwas untouched — the QA report (DOC-60) listed it as affected, but after the v0.10.6 multiplatform unification the page no longer contains thesetResponseFormatType(::class)construct and already uses the correctLeapStr/LeapArr/...names.Test plan
npx mintlify devfrom the worktree boots cleanly with no MDX parse errors./deployment/on-device/android/*, 10/deployment/on-device/ios/*, plus:slug*wildcards and theleap/edge-sdk/*paths) return 307 redirects to/deployment/on-device/sdk/*.cac3d06. Post-fix audit performed three times (each pass surfaced new discrepancies, see Bonus).leap-android-sdk@cac3d06per package:leap-sdk,leap-sdk-model-downloader,leap-sdk-openai-client,leap-ui.Refs DOC-27, DOC-37, DOC-38, DOC-39, DOC-40, DOC-41, DOC-42, DOC-43, DOC-44, DOC-45, DOC-46, DOC-47, DOC-48, DOC-49, DOC-50, DOC-51, DOC-52, DOC-53, DOC-54, DOC-55, DOC-56, DOC-57, DOC-58, DOC-59, DOC-60.